package net.wanho.controller;

import lombok.RequiredArgsConstructor;
import net.wanho.entity.Student;
import net.wanho.vo.StudentVo;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Author：汤小洋
 * Date：2024-01-29 14:51
 * Description：<描述>
 */
@RestController
@RequestMapping("/doc")
@RequiredArgsConstructor
public class DocController {

    private final ElasticsearchRestTemplate restTemplate;

    /**
     * 创建文档
     */
    @RequestMapping("/create")
    public String create(){
        restTemplate.save(new Student(1,"张三",18,"男","清华大学"));
        return "success";
    }

    /**
     * 批量创建文档
     */
    @RequestMapping("/batch")
    public String batch(){
        List<Student> list = new ArrayList<>();
        list.add(new Student(2,"李四",19,"男","北京大学"));
        list.add(new Student(3,"王五",20,"男","复旦大学"));
        list.add(new Student(4,"赵六",21,"女","上海交通大学"));
        list.add(new Student(5,"田七",22,"男","南京大学"));
        list.add(new Student(6,"周八",23,"女","浙江大学"));
        list.add(new Student(7,"吴九",24,"女","武汉大学"));
        list.add(new Student(8,"郑十",25,"男","中山大学"));
        restTemplate.save(list);
        return "success";
    }

    /**
     * 根据id查询
     */
    @RequestMapping("/{id}")
    public Student findById(@PathVariable Integer id){
        Student student = restTemplate.get(id.toString(), Student.class);
        return student;
    }

    /**
     * 查询所有
     */
    @RequestMapping("/all")
    public List<Student> findAll(){
        SearchHits<Student> hits = restTemplate.search(Query.findAll(), Student.class);

        System.out.println(hits.getTotalHits());
        List<Student> list = hits.stream()
                .map(hit -> hit.getContent())
                .collect(Collectors.toList());
        return list;
    }

    /**
     * 根据条件查询
     * 排序
     * 分页
     */
    @RequestMapping("/search/{school}/{minAge}/{maxAge}")
    public List<Student> search(@PathVariable String school, @PathVariable Integer minAge, @PathVariable Integer maxAge){
        // QueryBuilder queryBuilder = QueryBuilders.matchQuery("school", school);
        // QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").gte(minAge).lte(maxAge);

        // BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
        //         .must(QueryBuilders.matchQuery("school", school))
        //         .must(QueryBuilders.rangeQuery("age").gte(minAge).lte(maxAge));
        //
        // NativeSearchQuery query = new NativeSearchQuery(queryBuilder);

        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.rangeQuery("age").gte(minAge).lte(maxAge)) // 查询条件
                .withSort(Sort.by(Sort.Direction.DESC,"age")) // 排序
                .withPageable(PageRequest.of(0, 2)) // 分页
                .withSourceFilter(new FetchSourceFilter(new String[]{"id", "name","age","school"}, null)) // 过滤字段
                .build();

        SearchHits<Student> hits = restTemplate.search(query, Student.class);
        List<Student> list = hits.stream()
                .map(hit -> hit.getContent())
                .collect(Collectors.toList());
        return list;
    }

    /**
     * 高亮显示
     */
    @RequestMapping("/highlight/{school}")
    public List<StudentVo> hightlight(@PathVariable String school){
        // 设置高亮字段，并添加前缀和后缀
        HighlightBuilder highlightBuilder = new HighlightBuilder()
                .field("school")
                .preTags("<span style='color:red; font-weight:bold;'>") // 前缀
                .postTags("</span>"); // 后缀

        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("school", school))
                .withHighlightBuilder(highlightBuilder)
                .build();

        SearchHits<StudentVo> hits = restTemplate.search(query, StudentVo.class);
        List<StudentVo> list = hits.stream()
                .map(hit -> {
                    StudentVo studentVo = hit.getContent();
                    // 获取高亮字段，并处理
                    // <span style='color:red; font-weight:bold;'>南</span><span style='color:red; font-weight:bold;'>京</span>
                    String highlightField = hit.getHighlightField("school").stream().collect(Collectors.joining());
                    studentVo.setHighlightField(highlightField);
                    return studentVo;
                })
                .collect(Collectors.toList());
        return list;
    }

}
